package com.aaron.config;

import com.aaron.registry.zk.util.CuratorUtils;
import com.aaron.remoting.transport.netty.server.NettyRpcServer;
import com.aaron.utils.concurrent.threadpool.ThreadPoolFactoryUtils;
import lombok.extern.slf4j.Slf4j;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;

/**
 * 该类作用：清除zk中的注册信息 和 关闭线程。
 */
@Slf4j
public class CustomShutdownHook {
    private static final CustomShutdownHook CUSTOM_SHUTDOWN_HOOK = new CustomShutdownHook();

    public static CustomShutdownHook getCustomShutdownHook() {
        return CUSTOM_SHUTDOWN_HOOK;
    }

    // 这里貌似是在做事先清理，重启等问题 需要事先清除缓存的
    public void clearAll() {
        log.info("addShutdownHook for clearAll");
        /**
         * addShutdownHook()方法： 根据 Java API, 所谓 shutdown hook 就是已经初始化但尚未开始执行的线程对象。
         * 在Runtime 注册后，如果JVM要停止前，这些 shutdown hook便开始执行。也就是在你的程序结束前，执行一些清理工作，尤其是没有用户界面的程序。
         * 这些 shutdown hook 都是些线程对象，因此，你的清理工作要写在 run() 里。根据 Java API，你的清理工作不能太重了，要尽快结束。
         * 但仍然可以对数据库进行操作。问题是这个度该如何把握。
         */
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try {
                // 新建InetSocketAddress
                InetSocketAddress inetSocketAddress = new InetSocketAddress(InetAddress.getLocalHost().getHostAddress(), NettyRpcServer.PORT);
                // 清除所有zookeeper上的该套接字地址的 注册信息，CuratorUtils是自定义工具类
                CuratorUtils.clearRegistry(CuratorUtils.getZkClient(), inetSocketAddress);
            } catch (UnknownHostException ignored) {

            }
            // 关闭所有线程池，ThreadPoolFactoryUtils是自定义工具类
            ThreadPoolFactoryUtils.shutDownAllThreadPool();
        }));
    }
}
